/*  File Name	: ProcResult.cpp
 *  Author		: Javie Pong
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-8-12
 *  Description:
 */

#include "ProcResult.h"
#include "Logger.h"
#include <stdlib.h>
#include <algorithm>
#include "EnginePlayer.h"

ProcResult::ProcResult()
{
	this->type_ = NONE_TYPE;
	//this->role_id_ = 0;
	this->player_ = NULL;
	this->result_.clear();
}

ProcResult::~ProcResult()
{
	this->type_ = NONE_TYPE;
	this->player_ = NULL;
	this->result_.clear();
}

EnginePlayer *ProcResult::player(void)
{
	return this->player_;
}

CardVec &ProcResult::result(void)
{
	return this->result_;
}

//比较数字大小,如果然后按花色大小排序
int ProcResult::card_cmp_num(Card *c1,Card *c2)
{
	if(c1->number_==c2->number_)
	{
		return c1->type_ > c2->type_;
	}
	return c1->number_ > c2->number_;
}

//比较花色，如果相同则按数字大小排序
int ProcResult::card_cmp_type(Card *c1,Card *c2)
{
	if(c1->type_==c2->type_)
	{
		return c1->number_ > c2->number_;
	}
	return c1->type_ > c2->type_;
}

ResultType ProcResult::type(void)
{
	return this->type_;
}

int ProcResult::make_result(EnginePlayer *player,Card* pri_card[2],Card* pub_card[5])
{
	if(NULL==player)
	{
		return -1;
	}

	this->player_ = player;
	if(pri_card[0]->type_==CARDTYPE_NONE || pri_card[1]->type_==CARDTYPE_NONE)
	{
		LOG((ERROR_LOG,"ProcResult::make_result pri_card is null"));
		return -1;
	}

	CardVec tmp_vec;

	tmp_vec.push_back(pri_card[0]);
	tmp_vec.push_back(pri_card[1]);

	for(int i=0;i<5;i++)
	{
		if(CARDTYPE_NONE==pub_card[i]->type_)
		{
			LOG((ERROR_LOG,"ProcResult::make_result pub_card is null:%d",i));
			return -1;
		}
		tmp_vec.push_back(pub_card[i]);
	}

	this->identify_type(tmp_vec);
#ifdef DEBUG
	std::cout << "-result--role_id:" << this->player_->role_id();
	for (int i = 0; i < (int) result_.size(); i++)
	{
		Card *c = result_[i];
		std::cout << "-" << c->name_;
	}
	std::cout << std::endl;
#endif
	return 0;//this->identify_type(tmp_vec);
}

int ProcResult::identify_type(CardVec &vec)
{
#ifdef DEBUG
//	std::cout << std::endl;
//	std::sort(vec.begin(),vec.end(),ProcResult::card_cmp_type);
//	std::cout << "-cmp_type--role_id:" << this->player_->role_id();
//	for (int i = 0; i < (int)vec.size(); i++)
//	{
//		Card *c = vec[i];
//		std::cout << "-" << c->name_;
//	}
//	std::cout << std::endl;

	std::sort(vec.begin(), vec.end(), ProcResult::card_cmp_num);
	std::cout << "-cmp_num--role_id:" << this->player_->role_id();
	for (int i = 0; i < (int) vec.size(); i++)
	{
		Card *c = vec[i];
		std::cout << "-" << c->name_;
	}
	std::cout << std::endl;
#endif

	if(is_straight_or_royal_flush(vec)!=NONE_TYPE)
	{
		return 0;
	}
	else if(is_four_of_a_kind(vec)!=NONE_TYPE)
	{
		return 0;
	}
	else if(is_fullhouse(vec)!=NONE_TYPE)
	{
		return 0;
	}
	else if(is_suit(vec)!=NONE_TYPE)
	{
		return 0;
	}
	else if(is_three_of_a_kind(vec)!=NONE_TYPE)
	{
		return 0;
	}
	else if(is_two_pairs(vec)!=NONE_TYPE)
	{
		return 0;
	}
	else if(is_one_pair(vec)!=NONE_TYPE)
	{
		return 0;
	}
	else
	{
		for(int i=0;i<5;i++)
		{
			this->result_.push_back(vec[i]);
		}
		this->type_ = HIGH_CARD;
		return 0;
	}
	return 0;
}

//同花大顺或同花顺
ResultType ProcResult::is_straight_or_royal_flush(CardVec &vec)
{
	this->result_.clear();
	if((int)vec.size()!=7)
	{
		LOG((ERROR_LOG,"ProcResult::is_straight_or_royal_flush less card:[%d]",vec.size()));
		return NONE_TYPE;
	}

	int start_index = 0;
	std::sort(vec.begin(),vec.end(),ProcResult::card_cmp_type);

//	for(int i=0;i<7;i++)
//	{
//		Card *c = vec[i];
//		std::cout<<"id:"<<this->player_->role_id()<<"--card-type:"<< c->type_
//				<< "==card-num:"<< c->number_<<"-------"<<std::endl;
//	}

	for (int i = 0; i < 3; i++)
	{
		if ((vec[i]->number_ - 1) == (vec[i + 1]->number_)
				&& (vec[i + 1]->number_ - 1) == (vec[i + 2]->number_)
				&& (vec[i + 2]->number_ - 1) == (vec[i + 3]->number_)
				&& (vec[i + 3]->number_ - 1) == (vec[i + 4]->number_))
		{
			start_index = i;

			bool is_ths = true;
			for (int k = start_index; k <(start_index+5); k++)
			{//判断是否同花
				if (vec[k]->type_ != vec[start_index]->type_)
				{
					is_ths = false;
					break;
				}
			}
			if (is_ths) //如果是同花顺
			{
				this->type_ = STRAIGHT_FLUSH;
				for (int k = start_index; k < 5+start_index; k++)
				{
					this->result_.push_back(vec[k]);
				}

				if (vec[start_index]->number_ == MAX_CARD)
				{ //判断是否皇家同花顺
					this->type_ = ROYAL_FLUSH;
				}
				return this->type_;
			}
		}
	}
	return NONE_TYPE;
}

//四条
ResultType ProcResult::is_four_of_a_kind(CardVec &vec)
{
	this->result_.clear();
	if((int)vec.size()!=7)
	{
		LOG((ERROR_LOG,"ProcResult::is_four_of_a_kind less card:[%d]",vec.size()));
		return NONE_TYPE;
	}

	std::sort(vec.begin(),vec.end(),ProcResult::card_cmp_num);

	int start_index =0,max_card=-1;
	for (int i = 0; i < 4; i++)
	{
		if (vec[i]->number_ == vec[i + 1]->number_
				&& vec[i]->number_ == vec[i + 2]->number_
				&& vec[i]->number_ == vec[i + 3]->number_)
		{
			start_index = i;
			this->type_ = FOUR_OF_A_KIND;

			for(int j=i;j<i+4;j++)
			{
				this->result_.push_back(vec[j]);
			}
			if(max_card==-1)
			{
				max_card = i+4;
			}
			this->result_.push_back(vec[max_card]);

			return this->type_;
		}
		else if(max_card==-1)
		{
			max_card = i;
		}
	}
	return NONE_TYPE;
}

//葫芦（三条和一对)
ResultType ProcResult::is_fullhouse(CardVec &vec)
{
	this->result_.clear();
	if((int)vec.size()!=7)
	{
		LOG((ERROR_LOG,"ProcResult::is_fullhouse less card:[%d]",vec.size()));
		return NONE_TYPE;
	}
	std::sort(vec.begin(),vec.end(),ProcResult::card_cmp_num);

	int  pair_index = -1;
	for (int i = 0; i < 5; i++)
	{
		if (vec[i]->number_ == vec[i + 1]->number_)
		{
			if (vec[i]->number_ == vec[i + 2]->number_)
			{ //记录3条的位置
				if (pair_index != -1) //找到了对子
				{
					this->type_ = FULL_HOUSE;
				}
				else
				{ //在剩下的牌中找对子
					for (int j = i + 3; j < 6; j++)
					{
						if (vec[j]->number_ == vec[j + 1]->number_)
						{
							this->type_ = FULL_HOUSE;
							pair_index = j;
						}
					}
				}
				if (this->type_ == FULL_HOUSE)
				{
					for (int j = i; j < i + 3; j++)
					{
						this->result_.push_back(vec[j]);
					}
					this->result_.push_back(vec[pair_index]);
					this->result_.push_back(vec[pair_index + 1]);
					return this->type_;
				}
			}
			else if (pair_index == -1)
			{ //记录对子的位置,第一个对子是最大的
				pair_index = i;
			}
		}
	}
	return NONE_TYPE;
}

//同花
ResultType ProcResult::is_suit(CardVec &vec)
{
	this->result_.clear();
	if((int)vec.size()!=7)
	{
		LOG((ERROR_LOG,"ProcResult::is_suit less card:[%d]",vec.size()));
		return NONE_TYPE;
	}

	std::sort(vec.begin(),vec.end(),ProcResult::card_cmp_type);

	for (int i = 0; i < 3; i++)
	{
		if ((vec[i]->type_) == (vec[i + 1]->type_)
				&& (vec[i + 1]->type_) == (vec[i + 2]->type_)
				&& (vec[i + 2]->type_) == (vec[i + 3]->type_)
				&& (vec[i + 3]->type_) == (vec[i + 4]->type_))
		{
			this->type_ = SUIT;
			for (int j = i; j < i+5; j++)
			{
				this->result_.push_back(vec[j]);
			}
			return this->type_;
		}
	}
	return NONE_TYPE;
}

//顺子
ResultType ProcResult::is_straight(CardVec &vec)
{
	this->result_.clear();
	if((int)vec.size()!=7)
	{
		LOG((ERROR_LOG,"ProcResult::is_straight less card:[%d]",vec.size()));
		return NONE_TYPE;
	}

	std::sort(vec.begin(),vec.end(),ProcResult::card_cmp_num);

	for (int i = 0; i < 3; i++)
	{
		if ((vec[i]->number_ - 1) == (vec[i + 1]->number_)
				&& (vec[i + 1]->number_ - 1) == (vec[i + 2]->number_)
				&& (vec[i + 2]->number_ - 1) == (vec[i + 3]->number_)
				&& (vec[i + 3]->number_ - 1) == (vec[i + 4]->number_))
		{
			this->type_ = STRAIGHT;

			for (int j = i; j <(i+5); j++)
			{
				this->result_.push_back(vec[j]);
			}
			return this->type_;
		}
	}
	return NONE_TYPE;
}

//三条
ResultType ProcResult::is_three_of_a_kind(CardVec &vec)
{
	this->result_.clear();
	if((int)vec.size()!=7)
	{
		LOG((ERROR_LOG,"ProcResult::is_three_of_a_kind less card:[%d]",vec.size()));
		return NONE_TYPE;
	}

	std::sort(vec.begin(),vec.end(),ProcResult::card_cmp_num);

	for (int i = 0; i < 5; i++)
	{
		if (vec[i]->number_ == vec[i + 1]->number_)
		{
			if (vec[i]->number_ == vec[i + 2]->number_)
			{ //记录3条的位置

				this->type_ = THREE_OF_A_KIND;

				for (int j = i; j < i + 3; j++)
				{
					this->result_.push_back(vec[j]);
				}
				if (i == 0)
				{
					this->result_.push_back(vec[3]);
					this->result_.push_back(vec[4]);
				}
				else if (i == 1)
				{
					this->result_.push_back(vec[0]);
					this->result_.push_back(vec[4]);
				}
				else
				{
					this->result_.push_back(vec[0]);
					this->result_.push_back(vec[1]);
				}
				return this->type_;
			}
		}
	}
	return NONE_TYPE;
}

//两对
ResultType ProcResult::is_two_pairs(CardVec &vec)
{
	this->result_.clear();

	if((int)vec.size()!=7)
	{
		LOG((ERROR_LOG,"ProcResult::is_two_pairs less card:[%d]",vec.size()));
		return NONE_TYPE;
	}
	std::sort(vec.begin(),vec.end(),ProcResult::card_cmp_num);

	int pair_count=0,max_card = -1;
	for (int i = 0; i < 6; i++)
	{
		if (vec[i]->number_ == vec[i + 1]->number_)
		{
			this->result_.push_back(vec[i]);
			this->result_.push_back(vec[i+1]);
			i =i+1;//跳过一个数
			pair_count ++;
			if(pair_count>=2)
			{
				if(max_card==-1)
				{
					this->result_.push_back(vec[4]);
				}
				else
				{
					this->result_.push_back(vec[max_card]);
				}
				this->type_ = TWO_PAIRS;
				return this->type_;
			}
		}
		else if(max_card==-1)
		{
			max_card = i;
		}
	}
	return NONE_TYPE;
}

//一对
ResultType ProcResult::is_one_pair(CardVec &vec)
{
	this->result_.clear();

	if((int)vec.size()!=7)
	{
		LOG((ERROR_LOG,"ProcResult::is_one_pair less card:[%d]",vec.size()));
		return NONE_TYPE;
	}
	std::sort(vec.begin(),vec.end(),ProcResult::card_cmp_num);

	for (int i = 0; i < 6; i++)
	{
		if (vec[i]->number_ == vec[i + 1]->number_)
		{
			this->result_.push_back(vec[i]);
			this->result_.push_back(vec[i+1]);
			this->type_ = ONE_PAIR;

			if(i<=0)
			{
				this->result_.push_back(vec[2]);
				this->result_.push_back(vec[3]);
				this->result_.push_back(vec[4]);
			}
			else if(i<=1)
			{
				this->result_.push_back(vec[0]);
				this->result_.push_back(vec[3]);
				this->result_.push_back(vec[4]);
			}
			else if(i<=2)
			{
				this->result_.push_back(vec[0]);
				this->result_.push_back(vec[1]);
				this->result_.push_back(vec[4]);
			}
			else
			{
				this->result_.push_back(vec[0]);
				this->result_.push_back(vec[1]);
				this->result_.push_back(vec[2]);
			}
			return this->type_;
		}
	}
	return NONE_TYPE;
}
